<?php

namespace App\Services\Gongmall;


use think\Exception;

class  BaseService
{

    public  $appKey;
    public  $appSecret;
    public  $url;
    public  $serviceId;
    public  $pub;
    public  $is_encrypt;
    protected  $header = array() ; // 加密的消息头
    //需要加密的敏感信息
    private $encrypt_params = ['name', 'identity', 'bankAccountNo', 'mobile', 'bankAccount', 'alipayAccountNo'];

    public function __construct()
    {
        $config = config('app.gongmall');
        $this->appKey = $config['appKey'];
        $this->appSecret = $config['appSecret'];
        $this->url = $config['url'];
        $this->serviceId = $config['serviceId'];
        $this->pub = $config['pub'];
        $this->is_encrypt = $config['is_encrypt'];//是否启用加密
        if ($this->is_encrypt){
            $this->header = array('Authorization: RSA2048');
        }
    }

    // 获取毫秒时间戳
    public function getMilliseconds(): int
    {
        return (int)(microtime(true) * 1000);
    }

    // 使用工猫公钥进行数据加密
    public function encryptData($data): string{
        $public_key = "-----BEGIN PUBLIC KEY-----\n" . $this->pub . "\n-----END PUBLIC KEY-----\n";
        // 使用公钥加密数据
        openssl_public_encrypt($data, $encrypted_data, $public_key);

        return base64_encode($encrypted_data);
    }

    // 商户公钥加密
    public function mEncryptData($data)
    {
        $public_key = file_get_contents('../config/gongmall/public_key.pem');
        openssl_public_encrypt($data, $encrypted_data, $public_key);
        return $encrypted_data;
    }

    // 使用商户私钥进行解密
    public function decryptData($encrypted_data)
    {
        $encrypted_data = base64_decode($encrypted_data);
        $path = '../config/gongmall/private_key.pem';
        $private_key = file_get_contents($path);
        if (!$private_key){
            throw  new  Exception('私钥文件不存在'.$path);
        }
        // 使用私钥解密数据
        openssl_private_decrypt($encrypted_data, $decrypted_data, $private_key);
        return $decrypted_data;
    }

    public function array2Query($data){
        $query = '';
        foreach ($data as $key => $value) {
            if ($query !== '') {
                $query .= '&';
            }
            $query .= $key . '=' . $value;
        }
        return $query;
    }

    public function sendRequest($api, $params)
    {
        $nonce = mt_rand(10000, 99999) . time();
        gongmallLog('nonce:'.$nonce.' gongmall敏感信息加密前的请求参数:'.json_encode($params, JSON_UNESCAPED_UNICODE));
        // 加密敏感信息
        if ($this->is_encrypt){
            foreach ($this->encrypt_params as $en_p) {
                if (!empty($params[$en_p])) {
                    $params[$en_p] = $this->encryptData($params[$en_p]);
                }
            }
        }

        // 创建一个 cURL 句柄
        $ch = curl_init();
        $params['appKey'] = $this->appKey;
        $params['nonce'] = $nonce;
        $params['timestamp'] = $this->getMilliseconds();

        ksort($params, SORT_STRING);
        $string = $this->array2Query($params).'&appSecret='.$this->appSecret;
        $sign = strtoupper(md5($string));
        $params['sign'] = $sign;
        $url =  $this->url. $api.'?'.http_build_query($params);
        gongmallLog('nonce:'.$nonce.' gongmall request:'.$url);

        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, $url); // 设置请求的URL
        curl_setopt($ch, CURLOPT_POST, 1); // 设置使用POST方法
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $header = array('Content-Type: application/x-www-form-urlencoded');
        if ($this->is_encrypt) {
            array_push($header, 'Authorization: RSA2048');
        }
        //curl_setopt($ch, CURLOPT_HEADER, true);// 启用响应头
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        $result = curl_exec($ch);
        if (curl_errno($ch)) {
            echo 'Error:' . curl_error($ch);
        }
        // 获取响应头
        /*$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
        $responseHeader = substr($response, 0, $header_size);
        $body = substr($response, $header_size);
        preg_match_all('/^Authorization:(.*)$/mi', $responseHeader, $matches);
        $Authorization = trim(array_pop($matches[1]));*/

        curl_close($ch);
        $result = json_decode($result,true);
        // 解密敏感信息
        if ($this->is_encrypt && isset($result['data'])){
            foreach ($this->encrypt_params as $de_p) {
                if (!empty($result['data'][$de_p])) {
                    $result['data'][$en_p] = $this->decryptData($result['data'][$en_p]);
                }
            }

        }
        gongmallLog('nonce:'.$nonce.' gongmall 响应参数:success='.($result['success']?'true':'false').json_encode($result,JSON_UNESCAPED_UNICODE));
        return $result;

    }


}
